package core;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import core.EnergyMap;

public class GetEnergy {
	
	public static void main(String[] Args) throws IllegalArgumentException, IOException {
		GetEnergy energy = new GetEnergy(Utils.getImage("tower.jpg"));
		Utils.writeImage(energy.getImage(), "png", "test2.png");
	}
	
	// the image for energy
	private final BufferedImage image; 

	public GetEnergy(BufferedImage image) {
		this.image = image;
	}

	
	/**
	 * this determines the energy for a single pixel
	 * 
	 * @param x 	x-coordinate
	 * @param y		y-coordinate
	 * @return		the energy for the pixel
	 */
	private double getPixelEnergy(int x, int y) {
		double total = 0.0;
		int num = 0;
		Utils.RGB thisColor = new Utils.RGB(image.getRGB(x, y));
		
		//for all neighbors
		for (int neighborX = x - 1; neighborX <= x + 1; neighborX++)
			for (int neighborY = y - 1; neighborY <= y + 1; neighborY++) {
				//make sure x dimension is in bounds
				if (neighborX < 0 || neighborX >= image.getWidth() ||
					//make sure y dimension is in bounds
					neighborY < 0 || neighborY >= image.getHeight() ||
					//I don't care about this pixel
					(neighborX == x && neighborY == y))
						continue;
				
				//get the RGB for this test color
				//System.out.println("width: " + image.getWidth() + " height: " + image.getHeight() + " x: " + neighborX + " y: " + neighborY);
				Utils.RGB testColor = new Utils.RGB(image.getRGB(neighborX, neighborY));
				
				//add difference in RGB and add to total
				total += (Math.abs(thisColor.red - testColor.red) + 
					Math.abs(thisColor.green - testColor.green) + 
					Math.abs(thisColor.blue - testColor.blue));
				
				//we adjusted the number of color comparisons
				num++;
			}
		
		// 755 represents the total difference possible (255 * 3)
		return ((total / num) / 755);
	}
	
	/**
	 * creates an energy map from the given bufferedimage
	 * @return			the energy of the image
	 */
	public EnergyMap getEnergy() {
		double[][] arg = new double[image.getHeight()][image.getWidth()];
		
		for (int y = 0; y < image.getHeight(); y++)
			for (int x = 0; x < image.getWidth(); x++)
				arg[y][x] = getPixelEnergy(x, y);
		
		return new EnergyMap(arg);
	}
	
	
	/**
	 * get color based on energy
	 * 
	 * @param num		the energy value
	 * 
	 * @return			the energy color
	 */
	private int getEnergyColor(double num) {
		int intval = (int) (num * 255);
		return Utils.getIntFromRGB(intval, intval, intval);
	}
	
	/**
	 * Derives BufferedImage from EnergyMap
	 * @return
	 */
	public BufferedImage getImage() {
		EnergyMap emap = getEnergy();
		BufferedImage newImage = new BufferedImage(emap.getWidth(), emap.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
		
		for(int x = 0; x < emap.getWidth(); x++)
			for(int y = 0; y < emap.getHeight(); y++) {
				newImage.setRGB(x, y, getEnergyColor(emap.getEnergy(x, y)));
			}
		
		return newImage;
	}
	
	//I think it should be Files instead of BufferedImages due to memory concerns
	/**
	 * returns the Files that point to the animation for determining energy
	 *  
	 * @return		the files for animation
	 */
	public File[] getAnimPics() {
		//TODO fix
		return null;
	}
}